import numpy as np
import matplotlib.pyplot as plt

from mpl_toolkits.axes_grid1.inset_locator import inset_axes
from matplotlib.patches import ConnectionPatch

colors=['darkorange','blue','deeppink','black','limegreen','green','teal']
#点标记的样式 ^表示三角形，*五角星，o圆点，3箭头
markers=['s-','o-','x-','d-','^-','p-','*-']
scale = [0, 1, 2, 4, 6]
figsize=[6,5]
dpi=300
fontsize=12
linewidth=2.7
markersize=12

def draw(tasksList:list[int],filename:str):
    utilityDict = {}
    timeDict = {}
    memoryDict = {}
    responseDict = {}
    matchSizeDict = {}
    method = ''
    with open(filename, "r") as f:
        for item in f.readlines():
            items = item.split(" ")
            if method != items[0]:
                method = items[0]
                utilityDict.update({method: [float(items[1])]})
                timeDict.update({method: [float(items[2])]})
                memoryDict.update({method: [float(items[3])]})
                # responseDict.update({method:[float(items[4])]})
                matchSizeDict.update({method:[float(items[4])]})
            else:
                utilityDict[method].append(float(items[1]))
                timeDict[method].append(float(items[2]))
                memoryDict[method].append(float(items[3]))
                # responseDict[method].append(float(items[4]))
                matchSizeDict[method].append(float(items[4]))
    drawUtility(utilityDict,tasksList)
    drawTime(timeDict,tasksList)
    drawMemory(memoryDict,tasksList)
    # drawResponse(responseDict,tasksList)
    drawMatchSize(matchSizeDict,tasksList)

def drawUtility(utilityDict:dict,idx:list[int]):
    plt.figure(figsize=(figsize[0], figsize[1]), dpi=dpi)
    # plt.rcParams['font.sans-serif'] = ['STSong']  # 显示汉字
    plt.xlabel('|$\it{T}$|', fontsize=fontsize+6)  # x轴标题
    plt.ylabel('Utility', fontsize=fontsize+6)  # y轴标题
    #自定义横坐标的刻度
    # scale = np.arange(len(idx))
    plt.xticks(scale, idx)
    # plt.yticks(rotation=60)

    # ax = plt.gca()
    # ax.ticklabel_format(style='sci', scilimits=(-1, 2), axis='y', useMathText='%.2f×10$^{4}$')
    # ax.get_yaxis().get_offset_text().set(va='bottom', ha='left')
    # ax.yaxis.get_offset_text().set_fontsize(fontsize)

    colorNum = 0
    itemName = []
    for item in utilityDict:
        itemName.append(item)
        plt.plot(scale,utilityDict[item], markers[colorNum], color=colors[colorNum], linewidth=linewidth, markersize=markersize,
                 markerfacecolor='none')
        colorNum += 1
    plt.legend(itemName,loc='upper center')  # 设置折线名称
    plt.legend(itemName)  # 设置折线名称
    plt.legend(itemName,loc=10, bbox_to_anchor=(0.15, 0.8))  # 设置折线名称和图例的位置
    # plt.show()
    # axins = inset_axes(ax, width="30%", height="30%", loc='upper right',
    #                bbox_to_anchor=(0.35, 0.35, 0.5,0.5),
    #                bbox_transform=ax.transAxes)
    # optdata = utilityDict[list(utilityDict.keys())[0]]
    # ftgoadata = utilityDict[list(utilityDict.keys())[-1]]
    # optdata1 = []
    # ftgoadata1 = []
    #对两条比较接近的线的某个点进行放大，根据点生成数据
    # for n in range(2,0,-1):
    #     optdata1.append(optdata[int(len(optdata)/2)+1]-n)
    # optdata1.append(optdata[int(len(optdata)/2)+1])
    # for n in range(1,3):
    #     optdata1.append(optdata[int(len(optdata)/2)+1]+n*2)
    # for n in range(2,0,-1):
    #     ftgoadata1.append(ftgoadata[int(len(ftgoadata)/2)+1]-n)
    # ftgoadata1.append(ftgoadata[int(len(ftgoadata)/2)+1])
    # for n in range(1,3):
    #     ftgoadata1.append(ftgoadata[int(len(ftgoadata)/2)+1]+n*2)
    # axins.xaxis.set_ticks(scale, idx)#修改子图刻度
    # axins.scatter(scale[3],optdata1[int(len(optdata)/2)+1],c="none",marker="s", edgecolors=colors[0])
    # axins.scatter(scale[3],ftgoadata1[int(len(optdata)/2)+1],c="none",marker="p", edgecolors=colors[-1])
    # axins.plot(scale,optdata1,markers[0],color=colors[0],linewidth=linewidth*0.8,markersize=markersize*0,markerfacecolor='none')
    # axins.plot(scale,ftgoadata1,markers[-1],color=colors[-1],linewidth=linewidth*0.8,markersize=markersize*0,markerfacecolor='none')
    # axins.xaxis.set_ticks([scale[3]])#仅仅显示对应的刻度
    # axins.tick_params(labelsize=fontsize*0.8)
    #画框
    # xl = 0.2
    # yl =80
    # sx = [scale[3]-xl,scale[3]+xl,scale[3]+xl,scale[3]-xl,scale[3]-xl]
    # sy = [optdata[3]-yl,optdata[3]-yl,optdata[3]+yl,optdata[3]+yl,optdata[3]-yl]
    # ax.plot(sx,sy,"black",linewidth=linewidth*0.3)
    #画连线
    # xy = (scale[3]-xl,optdata[3]-yl)#主图点
    # xy2 = (axins.get_xlim()[0],axins.get_ylim()[0])#子图点 axins.get_ylim() 获取y轴的范围
    # con = ConnectionPatch(xyA=xy2,xyB=xy,coordsA="data",coordsB="data",
    #     axesA=axins,axesB=ax,linewidth=linewidth*0.3)
    # axins.add_artist(con)
    # xy = (scale[3]+xl,optdata[3]+yl)
    # xy2 = (axins.get_xlim()[1],axins.get_ylim()[1])
    # con = ConnectionPatch(xyA=xy2,xyB=xy,coordsA="data",coordsB="data",
    #     axesA=axins,axesB=ax,linewidth=linewidth*0.3)
    # axins.add_artist(con)
    plt.savefig("picture/taskUtility.png")
    plt.close()
    #计算不同方法倍数关系
    print("Utility")
    multiple = {}
    for j in utilityDict:
        if j !='OPT':
            temp=0
            nu = 0
            for k in utilityDict[j]:
                temp += k
                nu+=1
            temp = temp/nu
            multiple.update({j:temp})
    print(multiple)
    ETGOA = multiple["DQL(ours)"]
    for item in multiple:
        re = ETGOA/multiple[item]
        print("DQL(ours) up",item,":\t",str(round(re,2)))

def drawTime(timeDict:dict,idx:list[int]):
    plt.figure(figsize=(figsize[0], figsize[1]), dpi=dpi)
    # plt.rcParams['font.sans-serif'] = ['STSong']  # 显示汉字
    plt.xlabel('|$\it{T}$|', fontsize=fontsize+6)  # x轴标题
    plt.ylabel('Time(secs)', fontsize=fontsize+6)  # y轴标题
    plt.tick_params(labelsize=fontsize)
    # 自定义横坐标的刻度
    # scale = np.arange(len(idx))
    plt.xticks(scale, idx)
    # plt.yticks(rotation=60)

    # ax = plt.gca()
    # ax.ticklabel_format(style='sci', scilimits=(-1, 2), axis='y', useMathText='%.2f×10$^{4}$')
    # ax.get_yaxis().get_offset_text().set(va='bottom', ha='left')
    # ax.yaxis.get_offset_text().set_fontsize(fontsize)

    colorNum = 0
    itemName = []
    for item in timeDict:
        if item == 'OPT':
            colorNum+=1
            continue
        itemName.append(item)
        plt.plot(scale, timeDict[item], markers[colorNum], color=colors[colorNum], linewidth=linewidth,
                 markersize=markersize,
                 markerfacecolor='none')
        colorNum += 1
    plt.legend(itemName)  # 设置折线名称
    # plt.show()
    plt.savefig("picture/taskTime.png")
    plt.close()
    #计算不同方法倍数关系
    print("Time")
    multiple = {}
    for j in timeDict:
        if j !='OPT':
            temp=0
            nu = 0
            for k in timeDict[j]:
                temp += k
                nu+=1
            temp = temp/nu
            multiple.update({j:temp})
    print(multiple)
    ETGOA = multiple["DQL(ours)"]
    for item in multiple:
        re = multiple[item]/ETGOA
        print("DQL(ours) up",item,":\t",str(round(re,2)))

def drawMemory(memoryDict:dict,idx:list[int]):
    plt.figure(figsize=(figsize[0], figsize[1]), dpi=dpi)
    # plt.rcParams['font.sans-serif'] = ['STSong']  # 显示汉字
    plt.xlabel('|$\it{T}$|', fontsize=fontsize+6)  # x轴标题
    plt.ylabel('Memory(KB)', fontsize=fontsize+6)  # y轴标题
    plt.tick_params(labelsize=fontsize)
    # 自定义横坐标的刻度
    # scale = np.arange(len(idx))
    plt.xticks(scale, idx)
    plt.yticks(rotation=60)

    ax = plt.gca()
    ax.ticklabel_format(style='sci', scilimits=(-1, 2), axis='y', useMathText='%.2f×10$^{4}$')
    ax.get_yaxis().get_offset_text().set(va='bottom', ha='left')
    ax.yaxis.get_offset_text().set_fontsize(fontsize)

    colorNum = 0
    itemName = []
    for item in memoryDict:
        if item == 'OPT':
            colorNum += 1
            continue
        itemName.append(item)
        plt.plot(scale, memoryDict[item], markers[colorNum], color=colors[colorNum], linewidth=linewidth,
                 markersize=markersize,
                 markerfacecolor='none')
        colorNum += 1
    plt.legend(itemName)  # 设置折线名称
    # plt.show()
    plt.savefig("picture/taskMemory.png")
    plt.close()
    #计算不同方法倍数关系
    print("Momery")
    multiple = {}
    for j in memoryDict:
        if j !='OPT':
            temp=0
            nu = 0
            for k in memoryDict[j]:
                temp += k
                nu+=1
            temp = temp/nu
            multiple.update({j:temp})
    print(multiple)
    BGOA = multiple["DQL(ours)"]
    for item in multiple:
        re = (multiple[item]-BGOA)/multiple[item]
        print("DQL(ours) down",item,":\t",str(round(re*100,2)),"%")

def drawResponse(responseDict:dict,idx:list[int]):
    plt.figure(figsize=(figsize[0], figsize[1]), dpi=dpi)
    # plt.rcParams['font.sans-serif'] = ['STSong']  # 显示汉字
    plt.xlabel('|$\it{T}$|', fontsize=fontsize+6)  # x轴标题
    plt.ylabel('ARRTT(secs)', fontsize=fontsize+6)  # y轴标题  Average Real Response Time of Tasks
    plt.tick_params(labelsize=fontsize)
    # 自定义横坐标的刻度
    # scale = np.arange(len(idx))
    plt.xticks(scale, idx)

    ax = plt.gca()
    ax.ticklabel_format(style='sci', scilimits=(-1, 2), axis='y', useMathText='%.2f×10$^{4}$')
    ax.get_yaxis().get_offset_text().set(va='bottom', ha='left')
    ax.yaxis.get_offset_text().set_fontsize(fontsize)

    colorNum = 0
    itemName = []
    for item in responseDict:
        if item == 'OPT':
            colorNum += 1
            continue
        itemName.append(item)
        plt.plot(scale, responseDict[item], markers[colorNum], color=colors[colorNum], linewidth=linewidth,
                 markersize=markersize,
                 markerfacecolor='none')
        colorNum += 1
    plt.legend(itemName)  # 设置折线名称
    # plt.show()
    plt.savefig("picture/taskResponse.png")
    plt.close()
    #计算不同方法倍数关系
    print("Response")
    multiple = {}
    for j in responseDict:
        if j !='OPT':
            temp=0
            nu = 0
            for k in responseDict[j]:
                temp += k
                nu+=1
            temp = temp/nu
            multiple.update({j:temp})
    print(multiple)
    BGOA = multiple["DQL(ours)"]
    for item in multiple:
        re = multiple[item]/BGOA
        print("DQL(ours) up",item,":\t",str(round(re,2)))

def drawMatchSize(matchSizeDict:dict,idx:list[int]):
    plt.figure(figsize=(figsize[0], figsize[1]), dpi=dpi)
    # plt.rcParams['font.sans-serif'] = ['STSong']  # 显示汉字
    plt.xlabel('|$\it{T}$|', fontsize=fontsize+6)  # x轴标题
    plt.ylabel('Matching Size', fontsize=fontsize+6)  # y轴标题  
    plt.tick_params(labelsize=fontsize)
    # 自定义横坐标的刻度
    # scale = np.arange(len(idx))
    plt.xticks(scale, idx)

    ax = plt.gca()
    ax.ticklabel_format(style='sci', scilimits=(-1, 2), axis='y', useMathText='%.2f×10$^{4}$')
    ax.get_yaxis().get_offset_text().set(va='bottom', ha='left')
    ax.yaxis.get_offset_text().set_fontsize(fontsize)

    colorNum = 0
    itemName = []
    for item in matchSizeDict:
        # if item == 'OPT':
        #     colorNum += 1
        #     continue
        itemName.append(item)
        plt.plot(scale, matchSizeDict[item], markers[colorNum], color=colors[colorNum], linewidth=linewidth,
                 markersize=markersize,
                 markerfacecolor='none')
        colorNum += 1
    plt.legend(itemName)  # 设置折线名称
    plt.legend(itemName,loc=10, bbox_to_anchor=(0.5, 0.7))
    # plt.show()
    plt.savefig("picture/taskMatchSize.png")
    plt.close()


if __name__ =='__main__':
    tasksList=[500,1000,2500,5000,10000]
    draw(tasksList, "data/varytasks.txt")